#ifndef _VOL_HI_REDIS_H
#define _VOL_HI_REDIS_H

#include <hiredis.h>

class CVolRedisWraper
{
	private:
		redisContext* pContext;
	public:
		inline_ CVolRedisWraper() { pContext = NULL; }
		inline_ ~CVolRedisWraper() { Close(); }
		inline_ redisContext* SafeGetContext() { return (pContext == NULL || pContext->err) ? NULL : pContext; }
		inline_ BOOL IsConnected()
		{
			 redisReply* pReply = ExcCommand("PING");
			 if (pReply) { freeReplyObject (pReply); return TRUE; }
			 return FALSE;
		}
		void Close();
		void Connect(const char * ip, int port, const CVolString& password, unsigned int dbid, int timeout);
		
		redisReply* ExcCommand(const char *cmd);
		redisReply* ExcCommandExtend(const TCHAR* szParamTypes, const char *cmd, ...);
		
		BOOL AppendCommand(const char *cmd);
		BOOL AppendCommandExtend(const TCHAR* szParamTypes, const char *cmd, ...);
		redisReply* GetExcReply();
};

class CRedisReplyWrapper
{
	private:
		redisReply* pReply;
		BOOL isAutoDestroy;
	public:
		inline_ CRedisReplyWrapper() { pReply = NULL; isAutoDestroy = TRUE; }
		inline_ redisReply* GetReply() { ASSERT(pReply != NULL); return pReply; }
		inline_ BOOL IsValid() { return pReply != NULL; }
		inline_ ~CRedisReplyWrapper() { Destroy(); }
		
		inline_ void SetReply(redisReply* mReply, BOOL isDestroy = TRUE) 
		{ 
			if (pReply != NULL) 
				Destroy();
			pReply = mReply; 
			isAutoDestroy = isDestroy;
		}
		inline_ void Destroy()
		{
			if (isAutoDestroy && pReply != NULL)
				freeReplyObject(pReply);
			pReply = NULL; 
		}
};

#endif /* _VOL_HI_REDIS_H */
